package edu.uts.reekie.designer.implementation;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.gef.palette.*;
import org.eclipse.gef.requests.*;
import org.eclipse.gef.tools.MarqueeSelectionTool;

import edu.uts.reekie.designer.*;
import edu.uts.reekie.designer.implementation.model.*;
import edu.uts.reekie.designer.model.Note;


/*
 * 
 * TODO: add sticky notes for component responsibilities
 * TODO: add connectors
 */
public final class ViewPaletteFactory {


	private List<PaletteContainer> createCategories(PaletteRoot root){
		ArrayList<PaletteContainer> categories = new ArrayList<PaletteContainer>();
				
		
		categories.add(createControlGroup(root));
		categories.add(createConnectorsDrawer());
		categories.add(createComponentsDrawer());
		categories.add(createInterfacesDrawer());
		categories.add(createOtherDrawer());
		
		return categories;
	}
	
	private PaletteContainer createOtherDrawer() {
		PaletteDrawer drawer = new PaletteDrawer(
				"Other",
				ImageHelper.createDescriptorFromConceptualModelResource("icons/connectors.gif"));//$NON-NLS-1$
		List<PaletteEntry> entries = new ArrayList<PaletteEntry>();
		
		// 
		
		CombinedTemplateCreationEntry combined = new CombinedTemplateCreationEntry(
				"Note",
				"For note keeping on a view",
			new SimpleFactory(Note.class),
			ImageHelper.createDescriptorFromModelResource( "icons/note16.gif"), 
			ImageHelper.createDescriptorFromModelResource( "icons/note24.gif")
		);
		entries.add(combined);
		
		
		
		
		drawer.addAll(entries);
		
		return drawer;
	}
	
	private PaletteContainer createConnectorsDrawer() {
		PaletteDrawer drawer = new PaletteDrawer(
				Messages.Conceptual_Palette_Category_Connectors_Label,
				ImageHelper.createDescriptorFromImplementationModelResource("icons/connectors.gif"));//$NON-NLS-1$

		List<PaletteEntry> entries = new ArrayList<PaletteEntry>();
			
		// unidirectional and bidirectional connectors
		// TODO: add the connector stereotypes (see textbook)
			
		ConnectionCreationToolEntry tool = new ConnectionCreationToolEntry(
				Messages.Conceptual_Palette_CreationTool_UniDirectionalConnector_Label,
				Messages.Conceptual_Palette_CreationTool_UniDirectionalConnector_Description,
				new CreationFactory() {
					public Object getNewObject() { return null; }
					// see ShapeEditPart#createEditPolicies()
					// this is abused to transmit the desired line style 
					public Object getObjectType() { return new Integer(Connector.UNIDIRECTIONAL_CONNECTION); }
				},
				ImageHelper.createDescriptorFromImplementationModelResource("icons/uniconnector16.gif"),//$NON-NLS-1$
				ImageHelper.createDescriptorFromImplementationModelResource("icons/uniconnector24.gif")//$NON-NLS-1$
			);
		entries.add(tool);
		
		
		tool = new ConnectionCreationToolEntry(
				Messages.Conceptual_Palette_CreationTool_BiDirectionalConnector_Label,
				Messages.Conceptual_Palette_CreationTool_BiDirectionalConnector_Description,
				new CreationFactory() {
					public Object getNewObject() { return null; }
					// see ShapeEditPart#createEditPolicies()
					// this is abused to transmit the desired line style 
					public Object getObjectType() { return new Integer(Connector.BIDIRECTIONAL_CONNECTION); }
				},
				ImageHelper.createDescriptorFromImplementationModelResource("icons/biconnector16.gif"),//$NON-NLS-1$
				ImageHelper.createDescriptorFromImplementationModelResource("icons/biconnector24.gif")//$NON-NLS-1$
			);
		entries.add(tool);
		
		drawer.addAll(entries);
		return drawer;
		
	}

	
	private PaletteContainer createInterfacesDrawer() {
		PaletteDrawer drawer = new PaletteDrawer(
				Messages.Conceptual_Palette_Category_Interfaces_Label,
				ImageHelper.createDescriptorFromImplementationModelResource("icons/interfaces.gif"));//$NON-NLS-1$

			List<PaletteEntry> entries = new ArrayList<PaletteEntry>();
			
			// interfaces..
			
			// external interface
			// TODO: component interface
				
			
			CombinedTemplateCreationEntry combined = new CombinedTemplateCreationEntry(
				Messages.Conceptual_Palette_CreationTool_ExternalInterface_Label,
				Messages.Conceptual_Palette_CreationTool_ExternalInterface_Description,
				new SimpleFactory(ViewExternalInterface.class),
				
				ImageHelper.createDescriptorFromImplementationModelResource( "icons/externalinterface16.gif"), //$NON-NLS-1$
				ImageHelper.createDescriptorFromImplementationModelResource( "icons/externalinterface24.gif")//$NON-NLS-1$
			);
			entries.add(combined);
			
			
			drawer.addAll(entries);
			return drawer;
	}
	
	 private PaletteContainer createComponentsDrawer(){

		// TODO: move messages to the messages.properties file
		 
		PaletteDrawer drawer = new PaletteDrawer(
			"Components",
			ImageHelper.createDescriptorFromImplementationModelResource("icons/components.gif"));//$NON-NLS-1$

		List<PaletteEntry> entries = new ArrayList<PaletteEntry>();
		
		// The Components

		// app, infrastructure, container, file
		
		
		CombinedTemplateCreationEntry combined = new CombinedTemplateCreationEntry(
			"Application",
			"Application Component(s)",
			new SimpleFactory(ApplicationComponent.class),
			ImageHelper.createDescriptorFromImplementationModelResource( "icons/plain16.gif"), //$NON-NLS-1$
			ImageHelper.createDescriptorFromImplementationModelResource( "icons/plain24.gif")//$NON-NLS-1$
		);
		entries.add(combined);
		
		combined = new CombinedTemplateCreationEntry(
				"Infrastructure",
				"Infrastructure Component",
				new SimpleFactory(InfrastructureComponent.class)
				,
				ImageHelper.createDescriptorFromImplementationModelResource( "icons/infrastructure16.gif"), //$NON-NLS-1$
				ImageHelper.createDescriptorFromImplementationModelResource( "icons/infrastructure24.gif")//$NON-NLS-1$
			);
		entries.add(combined);

		combined = new CombinedTemplateCreationEntry(
				"Container",
				"Container Component",
				new SimpleFactory(ContainerComponent.class),
				ImageHelper.createDescriptorFromImplementationModelResource( "icons/container16.gif"), //$NON-NLS-1$
				ImageHelper.createDescriptorFromImplementationModelResource( "icons/container24.gif")//$NON-NLS-1$
			);
		entries.add(combined);
	
		combined = new CombinedTemplateCreationEntry(
				"File",
				"File Component(s)",
				new SimpleFactory(FileComponent.class),
				ImageHelper.createDescriptorFromImplementationModelResource( "icons/file16.gif"), //$NON-NLS-1$
				ImageHelper.createDescriptorFromImplementationModelResource( "icons/file24.gif")//$NON-NLS-1$
			);
		entries.add(combined);
		
		drawer.addAll(entries);
		return drawer;
	}

	 private PaletteContainer createControlGroup(PaletteRoot root){
		PaletteGroup controlGroup = new PaletteGroup(
			Messages.LogicPlugin_Category_ControlGroup_Label);

		List<PaletteEntry> entries = new ArrayList<PaletteEntry>();

		ToolEntry tool = new PanningSelectionToolEntry();
		entries.add(tool);
		root.setDefaultEntry(tool);

		PaletteStack marqueeStack = new PaletteStack(Messages.Marquee_Stack, "", null); //$NON-NLS-1$
		marqueeStack.add(new MarqueeToolEntry());
		MarqueeToolEntry marquee = new MarqueeToolEntry();
		marquee.setToolProperty(MarqueeSelectionTool.PROPERTY_MARQUEE_BEHAVIOR, 
				new Integer(MarqueeSelectionTool.BEHAVIOR_CONNECTIONS_TOUCHED));
		marqueeStack.add(marquee);
		marquee = new MarqueeToolEntry();
		marquee.setToolProperty(MarqueeSelectionTool.PROPERTY_MARQUEE_BEHAVIOR, 
				new Integer(MarqueeSelectionTool.BEHAVIOR_CONNECTIONS_TOUCHED 
				| MarqueeSelectionTool.BEHAVIOR_NODES_CONTAINED));
		marqueeStack.add(marquee);
		marqueeStack.setUserModificationPermission(PaletteEntry.PERMISSION_NO_MODIFICATION);
		entries.add(marqueeStack);
		
		
		controlGroup.addAll(entries);
		return controlGroup;
	}

	public PaletteRoot createPalette() {
		PaletteRoot palette = new PaletteRoot();
		palette.addAll(createCategories(palette));
		return palette;
	}
	
	
	
	
}
